﻿#include "Gobang.h"

int x = 0, y = 0;

static void ShowBoard(int board[][COL_G])
{
	system("cls");  //刷新界面
	printf("  ");
	for (int i = 0; i < COL_G; i++)
	{
		printf(" %3d ", i);
	}
	printf("\n  +--------------------------------------------------+\n");
	for (int i = 0; i < ROW_G; i++)
	{
		printf("%2d|", i);
		for (int j = 0; j < COL_G; j++)
		{
			if (board[i][j] == 0)
			{
				printf(" ﹡  ");
			}
			else if (board[i][j] == USER1)
			{
				printf(" ●  ");
			}
			else if (board[i][j] == USER2)
			{
				printf(" ○  ");
			}
		}
		printf("|\n");
	}
	printf("  +--------------------------------------------------+\n");
}

static void PlayMove(int board[][COL_G], int who)  //玩家操作
{
	while (1){
		printf("Please Enter Your Pos<x,y>[player%d]# ", who);
		scanf("%d %d", &x, &y);  //这里将玩家输入的坐标放进全局变量中，方便Judge函数
		if (x < 0 || x > ROW_G - 1 || y < 0 || y > COL_G - 1){
			printf("this postion is error!\n");
			continue;
		}
		if (board[x][y] == 0){
			board[x][y] = who;
			break;
		}
		else{
			printf("this postion is not empty!\n");
			continue;
		}
	}
}

static int ChessCount(int board[][COL_G], int dir)  //对某一棋子周边计数，用在Judge函数
{
	int _x = x;  //设置局部变量拷贝，防止改变原始值
	int _y = y;
	int count = 0;
	//状态机
	while (1){
		switch (dir){
		case UP:
			_x--;
			break;
		case RIGHT_UP:
			_y++, _x--;
			break;
		case RIGHT:
			_y++;
			break;
		case RIGHT_DOWN:
			_x++, _y++;
			break;
		case DOWN:
			_x++;
			break;
		case LEFT_DOWN:
			_x++, _y--;
			break;
		case LEFT:
			_y--;
			break;
		case LEFT_UP:
			_x--, _y--;
			break;
		default:
			printf("ChessCount bug!\n");
			break;
		}
		if (_x < 0 || _x > ROW_G - 1 || _y < 0 || _y > COL_G - 1){
			break;
		}
		else{
			if (board[x][y] != 0 && board[x][y] == board[_x][_y]){
				count++;
			}
			else{
				break;
			}
		}
	}
	return count;
}

static char JudgeGoband(int board[][COL_G])
{
	if (ChessCount(board, UP) + ChessCount(board, DOWN) >= 4 || \
		//统计上方和下方棋子数量，结果为竖直方向的同类棋子数
		ChessCount(board, RIGHT_UP) + ChessCount(board, LEFT_DOWN) >= 4 || \
		//统计右上方和左下方棋子数量，结果为右斜方向的同类棋子数
		ChessCount(board, RIGHT) + ChessCount(board, LEFT) >= 4 || \
		//统计右方和左方棋子数量，结果为水平方向的同类棋子数
		ChessCount(board, RIGHT_DOWN) + ChessCount(board, LEFT_UP) >= 4
		//统计右下和左上方棋子数量，结果为左斜方向的同类棋子数
		)
	{
		return board[x][y];
	}
	for (int i = 0; i < ROW_G; i++)  //判断是否平局
	{
		for (int j = 0; j < COL_G; j++)
		{
			if (board[i][j] == 0)
			{
				return NEXT_G;
			}
		}
	}
	return DRAW_G;
}

void Gobang()  //只能实现两用户对战
{
	int board[ROW_G][COL_G] = { 0 };
	char flag = 0;
	int curr = USER1;
	while (1)
	{
		ShowBoard(board);
		PlayMove(board, curr);
		flag = JudgeGoband(board);
		if (flag != NEXT_G)
		{
			break;
		}
		curr = (curr == USER1 ? USER2 : USER1);
	}
	ShowBoard(board);
	switch (flag){
	case USER1:
		printf("Player 1 win!\n");
		break;
	case USER2:
		printf("Player 2 win!\n");
		break;
	case DRAW_G:
		printf("DRAW!\n");
		break;
	default:
		printf("bug!\n");
		break;
	}

}